﻿using System;
using System.Data;
using KZ.Utilities;
using KZ.Express.H.ENT;
using KZ.Express.H.BLL;
using System.Collections.Generic;

namespace KZ.Express.H.Presenter
{
    public interface IBaseView
    {
        string ActionName { get; set; }

        SearchCriteria Search { get; }

        int EntityID { get; set; }

        BaseENT Entity { get; set; }

        DataTable Table { get; set; }

        void SetMessage(string message);

        bool ShowMessageConfirm(string message);

        void ChangeProgressBarVisible(bool isVisible);

        void ChangeProgressBarMaximum(int value);

        void PerformStepProgressBar(int value);

        void UpdateValueProgressBar(int value);
    }

    public interface IBasePresenter
    {
        void LoadEntity<T>();

        T LoadEntity<T>(int entityID);

        void LoadDataTable<T>();

        DataTable LoadDataTable<T>(SearchCriteria search);

        DataTable LoadDataTable(string query, SearchCriteria search);

        Dictionary<string, object> ExecuteNonQuery(string query, SearchCriteria search, params string[] outParameters);

        void Delete<T>(List<int> idList);

        void Save();
    }

    public class BasePresenter : IBasePresenter
    {
        protected int _isRecovery = 0;
        protected IBaseView _view;
        protected IBaseBLL _baseBLL;

        public BasePresenter(IBaseView view)
        {
            _view = view;
            _baseBLL = new BaseBLL();
        }

        public BasePresenter(IBaseView view, IBaseBLL baseBLL)
        {
            _view = view;
            _baseBLL = baseBLL;
        }

        public bool IsPermission(int objectID, int permissionID)
        {
            SearchCriteria search = new SearchCriteria();
            search.Add("ObjectID", objectID);
            search.Add("RoleID", UserENT._ROLEID);
            DataTable objects = _baseBLL.GetDataTable<ObjectENT>(search);

            string permission = "," + Utility.StringParse(objects.Rows[0]["PermissionID"]) + ",";
            return permission.Contains("," + permissionID + ",");
        }

        public virtual void LoadEntity<T>()
        {
            try
            {
                _view.SetMessage(String.Empty);
                _view.Entity = _baseBLL.GetByID<T>(_view.EntityID) as BaseENT;
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public virtual T LoadEntity<T>(int entityID)
        {
            try
            {
                _view.SetMessage(String.Empty);
                return _baseBLL.GetByID<T>(entityID);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public virtual void LoadDataTable<T>()
        {
            try
            {
                _view.SetMessage(String.Empty);
                _view.Table = _baseBLL.GetDataTable<T>(_view.Search);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public virtual DataTable LoadDataTable<T>(SearchCriteria search)
        {
            try
            {
                _view.SetMessage(String.Empty);
                return _baseBLL.GetDataTable<T>(search);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public virtual DataTable LoadDataTable(string query, SearchCriteria search)
        {
            try
            {
                _view.SetMessage(String.Empty);
                return _baseBLL.GetDataTable(query, search);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public Dictionary<string, object> ExecuteNonQuery(string query, SearchCriteria search, params string[] outParameters)
        {
            try
            {
                _view.SetMessage(String.Empty);
                return _baseBLL.ExecuteNonQuery(query, search, outParameters);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public virtual void Delete<T>(List<int> idList)
        {
            try
            {
                _baseBLL.Delete<T>(idList, UserENT._USERID, true);
                LoadDataTable<T>();
                _view.SetMessage("Dữ liệu đã xóa thành công");
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public virtual void Save()
        {
            BaseENT entity = _view.Entity;
            entity.IsRecovery = _isRecovery;

            try
            {
                if (_view.ActionName == "Insert")
                {
                    if (Utility.IntParse(_baseBLL.Insert(entity)) > 0)
                    {
                        _view.Entity = null;
                        _isRecovery = 0;
                        _view.SetMessage("Dữ liệu đã lưu thành công");
                    }
                }
                else if (_view.ActionName == "Update")
                {
                    if (Utility.IntParse(_baseBLL.Update(entity)) > 0)
                    {
                        _isRecovery = 0;
                        _view.SetMessage("Dữ liệu đã lưu thành công");
                    }
                }
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
            catch (BusinessLogicException ex)
            {
                if (entity.IsRecovery == 1)
                {
                    if (_view.ShowMessageConfirm(ex.Message))
                        _isRecovery = 1;
                    else
                        _isRecovery = 2;

                    Save();
                }
                else
                    throw new BusinessLogicException(ex.Message);
            }
        }
    }
}